package com.jw.service;

import com.jw.config.MinioProperties;
import com.jw.util.DateUtils;
import com.jw.util.UUIDUtils;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.Date;

@Service
public class MinioServiceImpl implements IMinioService {

    private final Logger logger = LoggerFactory.getLogger(MinioServiceImpl.class);

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioProperties minioProperties;

    @Override
    public Boolean bucketExists(String bucketName) {
        BucketExistsArgs args = BucketExistsArgs.builder().bucket(bucketName).build();
        try {
            return minioClient.bucketExists(args);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public String uploadFile(MultipartFile file) {
        return uploadFile(file, minioProperties.getBucketName());
    }

    @Override
    public String uploadFile(MultipartFile file, String bucketName) {
        String originalFilename = file.getOriginalFilename();
        String contentType = file.getContentType();
        logger.info("originalFilename:{}", originalFilename);
        logger.info("contentType:{}", contentType);
        String url;
        assert originalFilename != null;
        String fileName = UUIDUtils.generateUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        logger.info("fileName:{}", fileName);
        String objectName = DateUtils.parseFormatDate(new Date(), "yyyy-MM/dd") + "/" + fileName;
        logger.info("objectName:{}", objectName);
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();

            PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName)
                    .stream(inputStream, file.getSize(), -1).contentType(contentType).build();

            minioClient.putObject(putObjectArgs);
            url = minioProperties.getEndpoint() + "/" + bucketName + "/" + objectName;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return url;
    }

    @Override
    public String uploadImg(String imgStr) {
        return uploadImg(imgStr, minioProperties.getBucketName());
    }

    @Override
    public String uploadImg(String imgStr, String bucketName) {
        byte[] decode = Base64.getDecoder().decode(imgStr);
        return uploadImg(decode, bucketName);
    }

    @Override
    public String uploadImg(byte[] body) {
        return uploadImg(body, minioProperties.getBucketName());
    }

    @Override
    public String uploadImg(byte[] body, String bucketName) {
        InputStream byteArrayInputStream = new ByteArrayInputStream(body);
        String url = "";
        String fileName = UUIDUtils.generateUUID() + ".jpg";
        logger.info("fileName:{}", fileName);
        String objectName = DateUtils.parseFormatDate(new Date(), "yyyy-MM/dd") + "/" + fileName;
        logger.info("objectName:{}", objectName);
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName)
                    .stream(byteArrayInputStream, -1, 10485760).contentType("image/jpeg").build();
            minioClient.putObject(putObjectArgs);

            url = minioProperties.getEndpoint() + "/" + bucketName + "/" + objectName;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return url;
    }

}